<?php

namespace PhpYes\Modules\Cmd;


abstract class CmdArgumentDefinitions
{
    private $isExtracted;
    private $shortMapping;
    private $longMapping;
    private $requireMapping;
    private $requireValueMapping;

    public function __construct()
    {
        $this->isExtracted = false;
    }

    /**
     * @return ArgumentDefinition[]
     */
    abstract public function getArgumentDefinitions();

    /**
     * @return array - [short => ArgumentDefinition]
     */
    public function getShortMapping()
    {
        if (!$this->isExtracted) {
            $this->extractArgumentMapping();
        }

        return $this->shortMapping;
    }

    /**
     * @return array - [long => ArgumentDefinition]
     */
    public function getLongMapping()
    {
        if (!$this->isExtracted) {
            $this->extractArgumentMapping();
        }

        return $this->longMapping;
    }

    /**
     * @return array - [name => ArgumentDefinition]
     */
    public function getRequireMapping()
    {
        if (!$this->isExtracted) {
            $this->extractArgumentMapping();
        }

        return $this->requireMapping;
    }

    /**
     * @return array
     */
    public function getRequireValueMapping()
    {
        if (!$this->isExtracted) {
            $this->extractArgumentMapping();
        }

        return $this->requireValueMapping;
    }

    private function extractArgumentMapping()
    {
        if ($this->isExtracted) {
            return;
        }
        $this->isExtracted = true;

        $this->shortMapping = array();
        $this->longMapping = array();
        $this->requireMapping = array();
        $this->requireValueMapping = array();

        $argDefs = $this->getArgumentDefinitions();
        if ($argDefs) {
            foreach ($argDefs as $argDef) {
                $short = $argDef->getShort();
                $long = $argDef->getLong();
                if ($short) {
                    $this->shortMapping[$short] = $argDef;
                }
                if ($long) {
                    $this->longMapping[$long] = $argDef;
                }
                if ($argDef->isRequire()) {
                    $this->requireMapping[$argDef->getName()] = $argDef;
                }
                if ($argDef->isRequireValue()) {
                    $this->requireValueMapping[$argDef->getName()] = $argDef;
                }
            }
        }
    }

}